<template>
    <div class="game-container">
        <div class="header">
            <div class="scores">
                <div class="score">
                    <div class="label">得分</div>
                    <div class="value">{{ score }}</div>
                </div>
                <div class="score best">
                    <div class="label">最高分</div>
                    <div class="value">{{ bestScore }}</div>
                </div>
            </div>
            <div class="controls">
                <button @click="newGame">新游戏</button>
                <button @click="saveGameState">保存游戏</button>
                <button @click="goHome">返回主页</button>
            </div>
        </div>

        <div 
            class="game-grid" 
            @keydown="handleKeydown" 
            @touchstart="handleTouchStart"
            @touchmove.prevent="handleTouchMove"
            @touchend="handleTouchEnd"
            tabindex="0" 
            ref="gameGrid"
        >
            <div class="grid-background">
                <div v-for="i in 16" :key="i" class="grid-cell"></div>
            </div>
            <div class="tile-container">
                <div
                    v-for="tile in tiles"
                    :key="tile.id"
                    class="tile"
                    :class="[
                        `tile-${tile.value}`,
                        { 'tile-new': tile.isNew, 'tile-merged': tile.merged }
                    ]"
                    :style="getTileStyle(tile)"
                >
                    <span>{{ tile.value }}</span>
                </div>
            </div>
        </div>

        <div v-if="gameOver" class="game-over">
            <div class="message">游戏结束!</div>
            <div class="game-over-buttons">
                <button @click="newGame">再来一局</button>
                <button @click="goHome">返回主页</button>
            </div>
        </div>
    </div>
</template>

<script>
import { ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { saveGame, getSaves } from '../api'

export default {
    name: 'Game',
    setup() {
        const router = useRouter()
        const gameGrid = ref(null)
        const score = ref(0)
        const bestScore = ref(0)
        const tiles = ref([])
        const gameOver = ref(false)
        const grid = ref(Array(4).fill().map(() => Array(4).fill(null)))
        const currentSaveId = ref(null)
        let tileIdCounter = 0

        // 触摸相关状态
        let touchStartX = 0
        let touchStartY = 0
        const MIN_SWIPE_DISTANCE = 30 // 最小滑动距离

        const handleTouchStart = (event) => {
            touchStartX = event.touches[0].clientX
            touchStartY = event.touches[0].clientY
        }

        const handleTouchMove = (event) => {
            event.preventDefault() // 防止页面滚动
        }

        const handleTouchEnd = (event) => {
            const touchEndX = event.changedTouches[0].clientX
            const touchEndY = event.changedTouches[0].clientY

            const deltaX = touchEndX - touchStartX
            const deltaY = touchEndY - touchStartY

            // 判断是水平还是垂直方向的滑动
            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                // 水平滑动
                if (Math.abs(deltaX) >= MIN_SWIPE_DISTANCE) {
                    if (deltaX > 0) {
                        move('right')
                    } else {
                        move('left')
                    }
                }
            } else {
                // 垂直滑动
                if (Math.abs(deltaY) >= MIN_SWIPE_DISTANCE) {
                    if (deltaY > 0) {
                        move('down')
                    } else {
                        move('up')
                    }
                }
            }
        }

        const createTile = (position, value) => {
            return {
                id: tileIdCounter++,
                x: position.x,
                y: position.y,
                value: value || (Math.random() < 0.9 ? 2 : 4),
                isNew: true,
                merged: false
            }
        }

        const getTileStyle = (tile) => {
            const cellSize = 100 / 4; // 每个格子占容器的25%
            const gap = 15; // 间隙固定为15px
            const containerSize = gameGrid.value ? gameGrid.value.clientWidth - 30 : 0; // 减去两边的padding
            const cellSizeInPx = (containerSize - 3 * gap) / 4; // 实际的格子大小（像素）
            
            // 计算位置（像素）
            const left = tile.x * (cellSizeInPx + gap);
            const top = tile.y * (cellSizeInPx + gap);
            
            return {
                left: `${left}px`,
                top: `${top}px`,
                width: `${cellSizeInPx}px`,
                height: `${cellSizeInPx}px`,
                zIndex: tile.value
            }
        }

        const getAvailableCells = () => {
            const cells = []
            for (let x = 0; x < 4; x++) {
                for (let y = 0; y < 4; y++) {
                    if (!grid.value[x][y]) {
                        cells.push({ x, y })
                    }
                }
            }
            return cells
        }

        const addRandomTile = () => {
            const availableCells = getAvailableCells()
            if (availableCells.length) {
                const randomCell = availableCells[Math.floor(Math.random() * availableCells.length)]
                const newTile = createTile(randomCell)
                grid.value[randomCell.x][randomCell.y] = newTile
                tiles.value.push(newTile)
            }
        }

        const moveTile = (tile, newPosition) => {
            grid.value[tile.x][tile.y] = null
            tile.x = newPosition.x
            tile.y = newPosition.y
            grid.value[newPosition.x][newPosition.y] = tile
        }

        const mergeTiles = (tile1, tile2) => {
            grid.value[tile1.x][tile1.y] = null
            tile2.value *= 2
            tile2.merged = true
            score.value += tile2.value
            bestScore.value = Math.max(bestScore.value, score.value)
            const index = tiles.value.findIndex(t => t.id === tile1.id)
            if (index !== -1) {
                tiles.value.splice(index, 1)
            }
        }

        const move = (direction) => {
            if (gameOver.value) return

            const vectors = {
                up: { x: 0, y: -1 },
                right: { x: 1, y: 0 },
                down: { x: 0, y: 1 },
                left: { x: -1, y: 0 }
            }
            const vector = vectors[direction]
            
            let moved = false
            const traversals = {
                x: Array(4).fill().map((_, i) => i),
                y: Array(4).fill().map((_, i) => i)
            }

            if (vector.x === 1) traversals.x.reverse()
            if (vector.y === 1) traversals.y.reverse()

            traversals.x.forEach(x => {
                traversals.y.forEach(y => {
                    const tile = grid.value[x][y]
                    if (tile) {
                        let newX = x
                        let newY = y
                        let next
                        do {
                            newX += vector.x
                            newY += vector.y
                            if (newX < 0 || newX >= 4 || newY < 0 || newY >= 4) break
                            next = grid.value[newX][newY]
                        } while (next === null)

                        if (next && next.value === tile.value && !next.merged) {
                            mergeTiles(tile, next)
                            moved = true
                        } else {
                            const finalX = newX - vector.x
                            const finalY = newY - vector.y
                            if (finalX !== x || finalY !== y) {
                                moveTile(tile, { x: finalX, y: finalY })
                                moved = true
                            }
                        }
                    }
                })
            })

            if (moved) {
                tiles.value.forEach(tile => {
                    tile.isNew = false
                    tile.merged = false
                })
                addRandomTile()
                checkGameOver()
            }
        }

        const checkGameOver = async () => {
            if (getAvailableCells().length === 0) {
                const directions = ['up', 'right', 'down', 'left']
                const canMove = directions.some(direction => {
                    const vector = {
                        up: { x: 0, y: -1 },
                        right: { x: 1, y: 0 },
                        down: { x: 0, y: 1 },
                        left: { x: -1, y: 0 }
                    }[direction]

                    for (let x = 0; x < 4; x++) {
                        for (let y = 0; y < 4; y++) {
                            const tile = grid.value[x][y]
                            if (tile) {
                                const newX = x + vector.x
                                const newY = y + vector.y
                                if (newX >= 0 && newX < 4 && newY >= 0 && newY < 4) {
                                    const other = grid.value[newX][newY]
                                    if (other && other.value === tile.value) {
                                        return true
                                    }
                                }
                            }
                        }
                    }
                    return false
                })

                if (!canMove) {
                    gameOver.value = true
                    // 游戏结束时保存最终分数
                    const username = localStorage.getItem('username')
                    if (username) {
                        try {
                            const gameState = {
                                grid: Array(4).fill().map(() => Array(4).fill(0)),
                                score: score.value
                            }
                            
                            // 遍历网格，记录每个位置的数字
                            for (let x = 0; x < 4; x++) {
                                for (let y = 0; y < 4; y++) {
                                    const tile = grid.value[x][y]
                                    if (tile) {
                                        gameState.grid[x][y] = tile.value
                                    }
                                }
                            }
                            
                            await saveGame(username, gameState, score.value, currentSaveId.value)
                        } catch (error) {
                            console.error('保存游戏分数失败:', error)
                        }
                    }
                }
            }
        }

        const handleKeydown = (event) => {
            if (gameOver.value) return

            const keyMap = {
                'ArrowUp': 'up',
                'ArrowRight': 'right',
                'ArrowDown': 'down',
                'ArrowLeft': 'left'
            }

            const direction = keyMap[event.key]
            if (direction) {
                event.preventDefault()
                move(direction)
            }
        }

        const newGame = () => {
            score.value = 0
            gameOver.value = false
            tiles.value = []
            grid.value = Array(4).fill().map(() => Array(4).fill(null))
            currentSaveId.value = null // 重置存档ID
            addRandomTile()
            addRandomTile()
            if (gameGrid.value) {
                gameGrid.value.focus()
            }
        }

        const loadGameProgress = async () => {
            const username = localStorage.getItem('username')
            if (!username) {
                router.push('/')
                return
            }

            // 检查是否有选中的存档
            const currentSave = localStorage.getItem('currentSave')
            if (currentSave) {
                try {
                    // 从选中的存档加载
                    const saveData = JSON.parse(currentSave)
                    const gameState = typeof saveData.game_state === 'string' 
                        ? JSON.parse(saveData.game_state) 
                        : saveData.game_state
                    
                    // 保存当前存档ID
                    currentSaveId.value = saveData.id
                    
                    // 恢复分数
                    score.value = gameState.score || saveData.current_score
                    
                    // 重置游戏网格
                    tiles.value = []
                    grid.value = Array(4).fill().map(() => Array(4).fill(null))
                    
                    // 根据保存的网格数据恢复游戏状态
                    if (gameState.grid && Array.isArray(gameState.grid)) {
                        for (let x = 0; x < 4; x++) {
                            for (let y = 0; y < 4; y++) {
                                const value = gameState.grid[x][y]
                                if (value && value > 0) {
                                    const newTile = createTile({ x, y }, value)
                                    newTile.isNew = false // 防止加载时显示动画
                                    grid.value[x][y] = newTile
                                    tiles.value.push(newTile)
                                }
                            }
                        }
                    }
                    
                    // 清除当前存档信息，避免下次进入时重复加载
                    localStorage.removeItem('currentSave')
                    
                    // 获取用户最高分
                    try {
                        const { data } = await getSaves(username)
                        if (data.saves && data.saves.length > 0) {
                            const highestScore = Math.max(...data.saves.map(save => save.current_score))
                            bestScore.value = Math.max(bestScore.value, highestScore)
                        }
                    } catch (error) {
                        console.error('获取最高分失败:', error)
                    }
                } catch (error) {
                    console.error('加载存档失败:', error)
                    newGame()
                }
            } else {
                // 如果没有选中的存档，开始新游戏
                newGame()
                // 仍然获取最高分
                try {
                    const { data } = await getSaves(username)
                    if (data.saves && data.saves.length > 0) {
                        const highestScore = Math.max(...data.saves.map(save => save.current_score))
                        bestScore.value = Math.max(bestScore.value, highestScore)
                    }
                } catch (error) {
                    console.error('获取最高分失败:', error)
                }
            }
            
            // 确保游戏网格获得焦点
            if (gameGrid.value) {
                gameGrid.value.focus()
            }
        }

        const saveGameState = async () => {
            const username = localStorage.getItem('username')
            if (!username) {
                router.push('/')
                return
            }

            // 保存每个格子的状态
            const gameState = {
                grid: Array(4).fill().map(() => Array(4).fill(0)), // 初始化为全0的4x4网格
                score: score.value
            }

            // 遍历网格，记录每个位置的数字
            for (let x = 0; x < 4; x++) {
                for (let y = 0; y < 4; y++) {
                    const tile = grid.value[x][y]
                    if (tile) {
                        gameState.grid[x][y] = tile.value
                    }
                }
            }

            try {
                await saveGame(username, gameState, score.value, currentSaveId.value)
                alert('游戏已保存')
            } catch (error) {
                console.error('保存游戏失败:', error)
                alert('保存游戏失败')
            }
        }

        const goHome = async () => {
            router.push('/')
        }

        onMounted(() => {
            loadGameProgress() // 替换原来的newGame()调用
            window.addEventListener('keydown', handleKeydown)
        })

        onUnmounted(() => {
            window.removeEventListener('keydown', handleKeydown)
        })

        return {
            gameGrid,
            score,
            bestScore,
            tiles,
            gameOver,
            getTileStyle,
            handleKeydown,
            handleTouchStart,
            handleTouchMove,
            handleTouchEnd,
            newGame,
            saveGameState,
            goHome
        }
    }
}
</script>

<style scoped>
.game-container {
    max-width: 500px;
    margin: 40px auto;
    padding: 30px;
    height: calc(100vh - 80px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    width: calc(100% - 60px);
    background: #faf8ef;
    border-radius: 10px;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    flex-wrap: wrap;
    gap: 10px;
}

.scores {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.score {
    background: #bbada0;
    padding: 10px 20px;
    border-radius: 6px;
    color: white;
    min-width: 100px;
}

.label {
    font-size: 14px;
}

.value {
    font-size: 24px;
    font-weight: bold;
}

.controls {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

button {
    padding: 10px 20px;
    font-size: 16px;
    background-color: #8f7a66;
    color: white;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    white-space: nowrap;
}

button:hover {
    background-color: #776e65;
}

.game-grid {
    position: relative;
    background: #bbada0;
    padding: 15px;
    border-radius: 6px;
    width: 100%;
    aspect-ratio: 1;
    max-width: 500px;
    max-height: 500px;
    margin: 0 auto;
    outline: none;
    touch-action: none;
    box-sizing: border-box;
}

.grid-background {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 15px;
    position: absolute;
    inset: 15px;
    width: calc(100% - 30px);
    height: calc(100% - 30px);
}

.grid-cell {
    background: rgba(238, 228, 218, 0.35);
    border-radius: 3px;
    aspect-ratio: 1;
}

.tile-container {
    position: absolute;
    inset: 15px;
    width: calc(100% - 30px);
    height: calc(100% - 30px);
}

.tile {
    position: absolute;
    border-radius: 3px;
    transition: all 0.15s ease-in-out;
    background: #eee4da;
    color: #776e65;
    display: flex;
    justify-content: center;
    align-items: center;
    font-weight: bold;
    width: calc((100% - 45px) / 4);
    height: calc((100% - 45px) / 4);
}

.tile span {
    font-size: min(7vw, 35px);
    line-height: 1;
}

.tile-2 { background: #eee4da; }
.tile-4 { background: #ede0c8; }
.tile-8 { background: #f2b179; color: #f9f6f2; }
.tile-16 { background: #f59563; color: #f9f6f2; }
.tile-32 { background: #f67c5f; color: #f9f6f2; }
.tile-64 { background: #f65e3b; color: #f9f6f2; }
.tile-128 { background: #edcf72; color: #f9f6f2; font-size: 45px; }
.tile-256 { background: #edcc61; color: #f9f6f2; font-size: 45px; }
.tile-512 { background: #edc850; color: #f9f6f2; font-size: 45px; }
.tile-1024 { background: #edc53f; color: #f9f6f2; font-size: 35px; }
.tile-2048 { background: #edc22e; color: #f9f6f2; font-size: 35px; }

.tile-new {
    animation: appear 0.2s ease-in-out;
}

.tile-merged {
    animation: pop 0.2s ease-in-out;
}

.game-over {
    position: absolute;
    top: 15px;
    left: 15px;
    right: 15px;
    bottom: 15px;
    background: rgba(238, 228, 218, 0.73);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 100;
    border-radius: 6px;
}

.message {
    font-size: min(10vw, 60px);
    font-weight: bold;
    color: #776e65;
    margin-bottom: 30px;
    text-align: center;
}

.game-over-buttons {
    display: flex;
    gap: 20px;
}

@keyframes appear {
    0% { transform: scale(0); }
    100% { transform: scale(1); }
}

@keyframes pop {
    0% { transform: scale(0.8); }
    50% { transform: scale(1.2); }
    100% { transform: scale(1); }
}

/* 移动端适配 */
@media (max-width: 500px) {
    .game-container {
        margin: 20px auto;
        padding: 15px;
        height: calc(100vh - 40px);
        width: calc(100% - 30px);
    }

    .header {
        margin-bottom: 15px;
    }

    .score {
        padding: 8px 15px;
        min-width: 80px;
    }

    .label {
        font-size: 12px;
    }

    .value {
        font-size: 20px;
    }

    button {
        padding: 8px 15px;
        font-size: 14px;
    }

    .tile span {
        font-size: min(7vw, 35px);
    }
}

/* 超小屏幕适配 */
@media (max-width: 350px) {
    .game-container {
        padding: 5px;
    }

    .header {
        margin-bottom: 10px;
    }

    .score {
        padding: 6px 12px;
        min-width: 70px;
    }

    .label {
        font-size: 11px;
    }

    .value {
        font-size: 18px;
    }

    button {
        padding: 6px 12px;
        font-size: 13px;
    }

    .tile span {
        font-size: min(6vw, 30px);
    }
}
</style> 